package com.pic.others.service.impl;

import cn.hutool.json.JSONUtil;
import com.alibaba.nacos.client.naming.utils.CollectionUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.pic.common.utils.R;
import com.pic.common.utils.UserContext;
import com.pic.others.constants.category.ConnectionFlaskConstant;
import com.pic.others.domain.dto.category.CategoryWithOnePictureDTO;
import com.pic.others.domain.dto.category.CategoryWithPicturesDTO;
import com.pic.others.domain.dto.flask.FlaskCategoryDTO;
import com.pic.others.domain.po.Category;
import com.pic.others.domain.po.Picture;
import com.pic.others.domain.po.PictureCategory;
import com.pic.others.domain.po.PictureDescribe;
import com.pic.others.mapper.CategoryMapper;
import com.pic.others.mapper.PictureCategoryMapper;
import com.pic.others.mapper.PictureDescribeMapper;
import com.pic.others.mapper.PictureMapper;
import com.pic.others.service.ICategoryService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pic.others.service.IPictureService;
import com.pic.others.utils.ConnectionFlaskUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author koshi
 * @since 2023-11-24
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category> implements ICategoryService {

    private final PictureMapper pictureMapper;
    private final IPictureService pictureService;
    private final CategoryMapper categoryMapper;
    private final PictureCategoryMapper pictureCategoryMapper;
    private final PictureCategoryServiceImpl pictureCategoryService;
    private final PictureDescribeMapper pictureDescribeMapper;
    private final PictureDescribeServiceImpl pictureDescribeService;



    @Value("${flask.hosturl1}")
    private String ConnectionFlask;
    @Override
    public R<List<CategoryWithPicturesDTO>>     getCategoryWithPicture() {
        Long userId = UserContext.getUser();
        if(userId==null){
            return R.error("用户请先登录");
        }
        log.info("你在获取所有大类的图片,yeyeye");
//        List<Category>categories=categoryMapper.getFatherCategoryByUserId(userId);
        List<Category>categories=categoryMapper.getFatherCategory();


        List<CategoryWithPicturesDTO>dtos=new ArrayList<>();
        for(Category category:categories){
            log.info(category.getCategoryId().toString());
            CategoryWithPicturesDTO dto=new CategoryWithPicturesDTO();
            dto.setCategory(category);

            List<Long>pictureIds=pictureMapper.getNewFivePictureByCategory(category.getCategoryId(),userId);
            List<Picture>pictures=new ArrayList<>();
           for(Long picturesId:pictureIds){
               Picture byId = pictureService.getById(picturesId);
               pictures.add(byId);
           }
            dto.setPictures(pictures);
            dtos.add(dto);
        }
        log.info("ftheronedtos:{}",dtos);
        return R.success(dtos);
    }

    @Override
    public R<String> getCategoryInPython() {
        Long userId = UserContext.getUser();
        if(userId==null){
            return R.error("请登录");
        }
        List<Picture> pictures = pictureService.lambdaQuery()
                .eq(Picture::getUserId, userId).
                eq(Picture::getFlag,"False")
                .list();
        log.info("pictures.size():{}",pictures.size());
        // 更新图片标志
        if(pictures.size()==0){
            return R.success("");
        }
        String jsonString;
        try {
            jsonString = ConnectionFlaskUtils.getConnectionFlask(
                    ConnectionFlaskConstant.urlPath.GET_KEY_DESCRIBE,
                    "POST",
                    ConnectionFlaskConstant.key.PICTURE, JSONUtil.parse(pictures)

            );
        } catch (Exception e) {
            log.error("调用 Flask 服务出错", e);
            return R.error("出错了，请联系管理员");
        }

        if (jsonString == null) {
            return R.error("Flask 服务返回为空");
        }

        log.info("jsonString:{}",jsonString);
        // 批量更新数据库
        try {
            for(Picture picture:pictures){
                picture.setFlag("True");
                pictureMapper.updateById(picture);
            }
        } catch (Exception e) {
            log.error("更新数据库出错", e);
            return R.error("数据库更新失败");
        }

        ObjectMapper objectMapper = new ObjectMapper();

log.info("jsonString:"+jsonString);

        try {
            List<FlaskCategoryDTO> personList = Arrays.asList(objectMapper.readValue(jsonString, FlaskCategoryDTO[].class));
            // 现在你可以使用 personList 中的数据了
            for (int i=0;i<personList.size();i++) {
                FlaskCategoryDTO person = personList.get(i);
                String describe = null;
                if (person.getNumber() > 0) {
                    describe = person.getNumber() + "人,情绪是" + person.getMood().toString() + "性别是" + person.getGenders().toString();
                    describe = describe.replace("[", "").replace("]", ""); // 去掉【和】字符
                }
                StringBuffer thing = new StringBuffer();
                for (Map.Entry<String, Object> entry : person.getOthers().entrySet()) {
                    thing.append(entry.getKey() + "有" + entry.getValue() + "个,");
                }
                // 将 StringBuffer 转换为 String
                String thingString = thing.toString();
                thingString = thingString.replace("[", "").replace("]", "");

                PictureDescribe pictureDescribe = new PictureDescribe();

                pictureDescribe.setDescription(describe);
                //有人情况下再判断物品
                pictureDescribe.setUserId(userId);
                pictureDescribe.setThing(String.valueOf(thing));
                pictureDescribe.setPicId(pictures.get(i).getPicId());
                pictureDescribeService.save(pictureDescribe);


                if (person.getNumber() > 0) {//这是有人
                    //遍历这是几个人的种类
                    for (int j = 0; j < person.getNames().size(); j++) {
                        //遍历实际上是遍历名字加类名
                        Category category;
                        category = lambdaQuery().eq(Category::getCategoryEnglish, person.getNames().get(j)).one();
                        if (category == null) {//没有出现过这个的话
                            category = new Category();
                            category.setCategoryEnglish(person.getNames().get(j));
                            category.setCategoryContent("未命名");
                            category.setCreateTime(LocalDateTime.now());
                            category.setFatherNodeId(81L);
                            save(category);
                        }
                        PictureCategory pictureCategory = new PictureCategory();
                        pictureCategory.setPictureId(pictures.get(i).getPicId());
                        pictureCategory.setCategoryId(category.getCategoryId());
                        pictureCategory.setPictureDescribeId(pictureDescribe.getDescribeId());
                        pictureCategory.setUserId(userId);
                        pictureCategory.setFatherNodeId(81L);
                        pictureCategoryService.save(pictureCategory);
                    }
                }
                //接下来是物品的分类
                for (Map.Entry<String, Object> entry : person.getOthers().entrySet()) {
                    Category category = lambdaQuery().eq(Category::getCategoryEnglish, entry.getKey()).one();
                    PictureCategory pictureCategory=new PictureCategory();
                    pictureCategory.setFatherNodeId(category.getFatherNodeId());
                    pictureCategory.setPictureDescribeId(pictureDescribe.getDescribeId());
                    pictureCategory.setCategoryId(category.getCategoryId());
                    pictureCategory.setUserId(userId);
                    pictureCategory.setPictureId(pictures.get(i).getPicId());
                    pictureCategoryService.save(pictureCategory);
                }
            }


        } catch (IOException e) {
            e.printStackTrace();
        }
        return R.success("成功");


    }

    @Override
    public R<List<CategoryWithOnePictureDTO>> getCategoryPictureByFatherDTO() {
        Long userId = UserContext.getUser();
        if(userId==null){
            return R.error("用户未登录");
        }

        log.info("你在获取分类的图片:yeyeye");

        List<CategoryWithOnePictureDTO>dtos=new ArrayList<>();
        //得到用户已有的父
        List<Long>categoryIds=categoryMapper.getFatherCategoryByUserId(userId);
//        if(categoryIds==null||categoryIds.size()==0){
//            return R.error("还未图片，请上传图片后进行操作");
//        }
        for(Long ids:categoryIds){
            System.out.println("id:"+ids);
        }
        List<Category>categories=categoryMapper.selectBatchIds(categoryIds);
        log.info("我在getCategoryPictureByFatherDTO的size是{}",categories.size());
        for(Category category:categories){
            CategoryWithOnePictureDTO dto=new CategoryWithOnePictureDTO();
            dto.setCategory(category);
//            dto.setContent(category.getCategoryContent());
            //获取数据库中的最后一行数据

            PictureCategory pictureCategory = pictureCategoryMapper.selectOne(
                    new LambdaQueryWrapper<PictureCategory>()
                            .eq(PictureCategory::getUserId, userId)
                            .eq(PictureCategory::getFatherNodeId,category.getCategoryId())
                            .orderByDesc(PictureCategory::getPictureCategoryId)
                            .last("LIMIT 1")
            );
            log.info("我得到的pictureCategory:{}",pictureCategory);
            Picture picture=
                    pictureService.lambdaQuery().eq(Picture::getPicId,pictureCategory.getPictureId()).one();
            log.info("picture:{}",picture);
            if(picture==null){
                continue;
            }
            dto.setPicture(picture);
            dtos.add(dto);
        }
        log.info("fatherOne:dtos{}",dtos);
        return R.success(dtos);
    }

    /**
     * 整理下机制
     * 通过category得到查看picture_category中的信息,
     * 先假设这个节点是父亲节点，通过父节点查找这记录，查找不到，则知道这是二级节点的点击，即直接返回图片就行
     * 如果查找到了，即是父节点的点击，级返回二级节点分类以及第一张图
     * 如果通过
     * @param categoryId
     * @return
     */
    @Override
    public R<List<CategoryWithPicturesDTO>> getCategoryPictueByFatherId(Long categoryId) {
        Long userId = UserContext.getUser();
        if (userId == null) {
            return R.error("用户未登录");
        }
        log.info("得子类的id");
        List<CategoryWithPicturesDTO> dtos = new ArrayList<>();
//是否可以通过父类一起
        List<PictureCategory> pictureCategories = pictureCategoryService.lambdaQuery()
                .eq(PictureCategory::getUserId, userId)
                .eq(PictureCategory::getFatherNodeId, categoryId)
                .list();
//如果为空,即
        if (CollectionUtils.isEmpty(pictureCategories)) {//如果父没有找到
            pictureCategories = pictureCategoryService.lambdaQuery()
                    .eq(PictureCategory::getUserId, userId)
                    .eq(PictureCategory::getCategoryId, categoryId)
                    .list(); // 二级父节点

            //如果没有儿子节点
            if (CollectionUtils.isEmpty(pictureCategories)) {
                return R.error("未知错误");
            }

            //第二层的，即显示
            List<Long> pictureIds = pictureCategories.stream()
                    .map(PictureCategory::getPictureId)
                    .distinct()
                    .collect(Collectors.toList());

            List<Picture> pictures = pictureMapper.selectBatchIds(pictureIds);
            CategoryWithPicturesDTO dto = new CategoryWithPicturesDTO();
            dto.setPictures(pictures);
            dtos.add(dto);
        } else {//儿子的问题
            List<Long> childNoteIds = pictureCategories.stream()
                    .map(PictureCategory::getCategoryId)
                    .distinct()
                    .collect(Collectors.toList());

            for(Long chinld:childNoteIds){
                log.info("child:{}",chinld);
            }
            // 一次性获取子类的信息
            List<Category> childCategories = categoryMapper.selectList(
                    new QueryWrapper<Category>().in("category_id", childNoteIds)
            );

            for (Category category : childCategories) {
                CategoryWithPicturesDTO dto = new CategoryWithPicturesDTO();
                dto.setCategory(category);

                log.info("我的category.getCategoryId()：{}",category.getCategoryId());
                // 获取数据库中的最后一行数据
                PictureCategory pictureCategory = pictureCategoryMapper.selectOne(
                        new LambdaQueryWrapper<PictureCategory>()
                                .eq(PictureCategory::getUserId, userId)
                                .eq(PictureCategory::getCategoryId, category.getCategoryId())
                                .orderByDesc(PictureCategory::getPictureCategoryId)
                                .last("LIMIT 1")
                );
                log.info("循环.pictureCategory()：{}",pictureCategory.toString());
                if(pictureCategories==null){
                    return R.error("出错了请联系管理员");
                }
                Picture picture=pictureService.getById(pictureCategory.getPictureId());
                if(picture==null){
                    continue;
                }
                List<Picture>list=new ArrayList<>();
                list.add(picture);
                dto.setPictures(list);
                dtos.add(dto);
            }
        }
log.info(dtos.toString());
        return R.success(dtos);
    }


    @Override
    public R<List<Picture>> getPictureByCategory(Long categoryId) {
        Long userId = UserContext.getUser();
        if(userId==null){
            return R.error("用户未登录，请登录");
        }
        List<Long> pictureIds = pictureCategoryService.lambdaQuery()
                .eq(PictureCategory::getCategoryId, categoryId)
                .list()
                .stream()
                .map(PictureCategory::getPictureId)
                .collect(Collectors.toList());
        List<Picture>pictures=pictureMapper.selectBatchIds(pictureIds);


        return R.success(pictures);
    }

    @Override
    public R<String> changeCategoryName(Long categoryId, String value) {
        boolean flag = lambdaUpdate().eq(Category::getCategoryId, categoryId).set(
                Category::getCategoryContent, value
        ).update();
        if(flag){
            return R.success("更新成功");
        }
        return R.error("未知错误，请联系管理员");
    }

//    @Override
//    public R<List<Category>> getAllChildCategories() {
//        Long userId = UserContext.getUser();
//        if(userId==null){
//            return R.error("请先登录");
//        }
//
//    }
}
